#pragma once
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <boost/algorithm/string.hpp>
#include <mutex>
#include "./cppjieba/Jieba.hpp"
#include "../log/log.hpp"
namespace bs_util
{
    class file_util
    {
    public:
        static bool read_file(const std::string &file_path, std::string &output, const std::ios_base::openmode mode)
        {
            // 输入文件流对象
            std::ifstream ifs(file_path.c_str(), mode);
            if (!ifs.is_open())
            {
                boost_searcher::searcher_log(FATAL, "failed to open input file: " + file_path);
                return false;
            }
            // 按行读取 并输出
            for (std::string tmp; std::getline(ifs, tmp); output += tmp)
                ;
            ifs.close();
            return true;
        }
    };
    class string_util
    {
    public:
        static void split(const std::string &target, std::vector<std::string> &out, const std::string &sep)
        {
            // boost split
            boost::split(out, target, boost::is_any_of("\3"), boost::token_compress_on);
        }
    };
    // 词库路径
    const char *const DICT_PATH = "/home/hly/project/boost_searcher/util/dict/jieba.dict.utf8";
    const char *const HMM_PATH = "/home/hly/project/boost_searcher/util/dict/hmm_model.utf8";
    const char *const USER_DICT_PATH = "/home/hly/project/boost_searcher/util/dict/user.dict.utf8";
    const char *const IDF_PATH = "/home/hly/project/boost_searcher/util/dict/idf.utf8";
    const char *const STOP_WORD_PATH = "/home/hly/project/boost_searcher/util/dict/stop_words.utf8";
    // 引用结巴工具进行分词
    class jieba_util
    {
    private:
        // 结巴对象
        cppjieba::Jieba _jieba;
        std::unordered_map<std::string, bool> stop_words;

    private:
        // 单例模式
        jieba_util() : _jieba(DICT_PATH, HMM_PATH, USER_DICT_PATH, IDF_PATH, STOP_WORD_PATH) { ; };
        jieba_util(const jieba_util &) = delete;
        jieba_util &operator=(const jieba_util &) = delete;
        static jieba_util *_instance;

    public:
        static jieba_util *get_instance()
        {
            static std::mutex mtx;
            if (nullptr == _instance)
            {
                mtx.lock();
                if (nullptr == _instance)
                {
                    _instance = new jieba_util;
                    boost_searcher::searcher_log(NORMAL, "init jieba_util:" + std::to_string((long long)_instance));
                    _instance->init_jieba_util();
                    boost_searcher::searcher_log(NORMAL, "init jieba_util successed");
                }
                mtx.unlock();
            }
            return _instance;
        }
        bool init_jieba_util()
        {
            std::ifstream in(STOP_WORD_PATH);
            if (!in.is_open())
            {
                boost_searcher::searcher_log(FATAL, "load stop wrods file error");
                return false;
            }
            std::string line;
            while (std::getline(in, line))
            {
                stop_words[line] = true;
            }
            in.close();
            return true;
        }
        void cut_string_helper(const std::string &str, std::vector<std::string> &out)
        {
            _jieba.CutForSearch(str, out);
            for (auto iter = out.begin(); iter != out.end();)
            {
                auto find_it = stop_words.find(*iter);
                find_it == stop_words.end() ? iter++ : iter = out.erase(iter);
            }
        }
        // 静态分词方法 提供给外部使用
        static void cut_string(const std::string &str, std::vector<std::string> &out)
        {
            bs_util::jieba_util::get_instance()->cut_string_helper(str, out);
        };
    };
    // 初始化结巴对象
    bs_util::jieba_util *jieba_util::_instance = nullptr;
};
